#include "Frame.h"

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <Summary>	Default constructor </Summary>
////////////////////////////////////////////////////////////////////////////////////////////////////
Frame::Frame(void)
{
	localMatrix.MakeIdentity();
	worldMatrix.MakeIdentity();
	parentFrame = NULL;
	dirtyFlag = true;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <Summary>	Gets the world matrix </Summary>
///
/// <Return>	The world matrix </Return>
/// 
/// <Remarks>	This is returned as a constant and should not be directly changed	</Remarks>
////////////////////////////////////////////////////////////////////////////////////////////////////
const Matrix4x4& Frame::GetWorldMatrix() 
{ 
	if(dirtyFlag)
	{
		if(parentFrame != NULL)
		{
			Multiply(worldMatrix, localMatrix, parentFrame->GetWorldMatrix());
		}
		else
		{
			worldMatrix = localMatrix;
		}
		dirtyFlag = false;
	}
	return worldMatrix; 
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <Summary>	Gets the local matrix </Summary>
///
/// <Return>	The local matrix </Return>
////////////////////////////////////////////////////////////////////////////////////////////////////
Matrix4x4& Frame::GetLocalMatrix() 
{
	Dirty();

	return localMatrix; 
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <Summary>	Sets the local matrix </Summary>
///
/// <Param name="mat">	The matrix </Param>
////////////////////////////////////////////////////////////////////////////////////////////////////
void Frame::SetLocalMatrix(const Matrix4x4* mat)
{
	Dirty();

	localMatrix = *mat;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <Summary>	Sets the parent </Summary>
///
/// <Param name="parent">	The new parent </Param>
////////////////////////////////////////////////////////////////////////////////////////////////////
void Frame::SetParent(Frame *parent) 
{ 
	dirtyFlag = true;
	parentFrame = parent; 
	parentFrame->children.Push_Front(this);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <Summary>	Sets the dirty flag for this object and all its children </Summary>
////////////////////////////////////////////////////////////////////////////////////////////////////
void Frame::Dirty(void)
{
	dirtyFlag = true;

	for(SLList<Frame*>::Iterator iter(children); !iter.End(); ++iter)
	{
		(*iter)->Dirty();
	}
}

